<template>
  <div class="slot">
    <slot></slot>
  </div>
</template>

<script lang="ts" setup>
import { AnySourceData } from "mapbox-gl";
import { addMarker, IMarker, map } from "../store";
import {
  onMounted,
  PropType,
  watch,
  provide,
  ref,
  render,
  h,
  createVNode,
  createApp,
  Component,
} from "vue";

import basicIcon from "@/assets/images/marker.png";
import mapboxgl from "mapbox-gl";
import { json } from "stream/consumers";
const props = defineProps({
  id: {
    type: String,
    required: true,
  },
  visible: {
    type: Boolean,
    default: true,
  },
  icon: {
    type: String,
    default: basicIcon,
  },
  type: {
    type: String,
    default: "marker",
  },
  popup: {
    type: Object as PropType<Component>,
  },
});
// console.log("popupDetail", popupDetail);
const itemList = [];
const source: AnySourceData = {
  type: "geojson",
  data: {
    type: "FeatureCollection",
    features: [],
  },
};
const addSymbol = (item) => {
  console.log("add item", item);
  if (!item.properties.icon) {
    item.properties.icon = props.icon;
  }
  itemList.push(item);
  addSource();
  // addMarker(item);
};
const updateSymbol = (item) => {
  for (let i = 0; i < itemList.length; i++) {
    if (item.id == itemList[i].id) {
      itemList[i] = item;
      addSource();
      return;
    }
  }
};
const removeSymbol = (item) => {
  for (let i = 0; i < itemList.length; i++) {
    if (item.id == itemList[i].id) {
      itemList.splice(i, 1);
      addSource();
      return;
    }
  }
};
watch(
  () => itemList,
  (val) => {},
  {
    // immediate: true,
  }
);
watch(
  () => props.visible,
  (val) => {
    // source.
    map.setLayoutProperty(
      "layer-" + props.id,
      "visibility",
      val == true ? "visible" : "none"
    );
  }
);
const addSource = () => {
  source.data["features"] = itemList.map((item) => {
    return item;
  });
  if (!map.getSource("source-" + props.id)) {
    map.addSource("source-" + props.id, source);
  } else {
    //@ts-ignore
    map.getSource("source-" + props.id).setData(source.data);
  }
};
const genLayerGeoJson = () => {};
const addLayer = () => {
  map.loadImage(props.icon, (err, image) => {
    if (!map.hasImage(props.icon)) {
      map.addImage(props.icon, image);
    }
  });
  if (!map.getLayer("layer-" + props.id)) {
    // Add a symbol layer
    if (!map.getLayer("layer-" + props.id)) {
      if (props.type == "marker") {
        map.addLayer({
          id: "layer-" + props.id,
          type: "symbol",
          source: "source-" + props.id,
          layout: {
            "icon-image": ["get", "icon"],
            "text-field": ["get", "title"], //文本内容来源字段
            "text-font": [
              //字体
              "Open Sans Semibold",
              "Arial Unicode MS Bold",
            ],
            "text-offset": [0, 2], //设置图标与图标注相对之间的距离
            "text-anchor": "top", //标记文本相对于定位点的位置
            "text-size": 12, //字号
            "icon-size": ["get", "size"], //图标的大小
            "icon-allow-overlap": true,
            "text-allow-overlap": true,
          },
          paint: {
            "text-color": "#fff",
          },
        });
      } else if (props.type == "LineString") {
        map.addLayer({
          id: "layer-" + props.id,
          type: "line",
          source: "source-" + props.id,
          layout: {
            //线条末端样式
            "line-cap": "round",
            //线条相交处样式
            "line-join": "round",
          },
          paint: {
            //设置线颜色
            "line-color": ["get", "color"],
            // "line-color":'red',
            //设置线宽度，像素单位
            "line-width": ["get", "width"],
            // "line-width":10
          },
        });
      }
    }
  }
};
const listenLayerClick = () => {
  map.on("click", "layer-" + props.id, (e: any) => {
    // Copy coordinates array.
    const features: any = map.queryRenderedFeatures(e.point, {
      layers: ["layer-" + props.id],
    });
    const _window: any = window;
    const coordinates = e.features[0].geometry.coordinates.slice();
    if (_window.popApp) {
      _window.popApp.unmount();
      _window.popApp = null;
    }
    console.log(features, features[0].properties);
    _window.popApp = createApp(props.popup, {
      lon: coordinates[0],
      lat: coordinates[1],
      title: features[0].properties.title,
      propData: JSON.parse(features[0].properties.userData),
    });
    const el = document.createElement("div");
    // render(_window.popApp, _window.el)
    _window.popApp.mount(el);
    // Ensure that if the map is zoomed out such that multiple
    // copies of the feature are visible, the popup appears
    // over the copy being pointed to.
    while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
      coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
    }
    // const vm = render
    const popup = new mapboxgl.Popup({
      closeButton: false,
    })
      .setLngLat(coordinates)
      .setDOMContent(el)
      .addTo(map);
    popup.on("close", () => {
      console.log("popup was closed");
    });
  });
};
onMounted(() => {
  addLayer();
  if (props.type == "marker") {
    listenLayerClick();
  }
});
provide("addSymbol", addSymbol);
provide("removeSymbol", removeSymbol);
provide("updateSymbol", updateSymbol);
</script>

<style lang="scss" scoped></style>
